# -*- coding:utf-8 -*-
import uuid
import datetime as dt
import json
import re
from datetime import datetime, timedelta
import requests
from wfs.models import *
from django.conf import settings
from tb_forms.models import TbApplyform
from method.email import sendMail
from ac.models import LoginToken
from files.method import change_status


def generate_no(lastNo, noTime):
    """
    用於生成NO.
    :param lastNo:
    :param noTime:
    :return: NO.
    """
    if lastNo:
        if lastNo[0].no[0:8] == noTime:
            lastno = int(lastNo[0].no)
            lastno += 1
        else:
            lastno = noTime + '0001'
    else:
        lastno = str(noTime) + '0001'
    return lastno


def mailtototot(username, workflow_id, customer_id=None, project_id=None):
    user22222 = User.objects.filter(username=username)[0]
    to = LoginToken.objects.filter(user_id=user22222.id).order_by('-end_date')
    if to:
        to = LoginToken.objects.filter(id=to[0].id).update(end_date=datetime.now() + timedelta(days=8))
    else:
        token = str(uuid.uuid4())
        to = LoginToken.objects.create(user_id=user22222.username, token=token,
                                       end_date=datetime.now() + timedelta(days=8))
    from files.models import TbApplyform
    from customer.models import TbCustomerPaper, TbProjectPaper
    if customer_id:
        cust_paper = TbCustomerPaper.objects.filter(id=customer_id)[0]
        sql = cust_paper.custters_spec + cust_paper.p_name + cust_paper.version

        if TbCustomerPaper.objects.filter(copy_id=customer_id):
            type = "客戶圖紙"
        else:
            type = "客戶變更圖紙"
        sendMail(user22222.email, settings.APPROVAL_SUB[3].format(user22222.last_name, type + "(" + sql + ")"),
                 settings.APPROVAL_CONTENT[3].format(user22222.last_name, type + "(" + sql + ")",
                 settings.SYSTEM_ADDRESS + settings.WEB_HRAD[2].format(customer_id, to.token,workflow_id)))

    elif project_id:
        pro_paper = TbProjectPaper.objects.filter(id=project_id)[0]
        sql = pro_paper.custters_spec + pro_paper.stage_type + pro_paper.cutter_type + pro_paper.version
        if TbProjectPaper.objects.filter(id_copy=project_id):
            type = "工程圖紙"
        else:
            type = "工程變更圖紙"
        sendMail(user22222.email, settings.APPROVAL_SUB[3].format(user22222.last_name, type + "(" + sql + ")"),
                 settings.APPROVAL_CONTENT[3].format(user22222.last_name, type + "(" + sql + ")",
                 settings.SYSTEM_ADDRESS + settings.WEB_HRAD[3].format(project_id, to.token,workflow_id)))

    else:
        a_form = TbApplyform.objects.filter(wrecord=workflow_id)
        if a_form:
            forms = a_form[0]
            if forms.customer_id:
                cust_paper = TbCustomerPaper.objects.filter(id=forms.customer_id)[0]
                sql = cust_paper.custters_spec + cust_paper.p_name + cust_paper.version
                if TbCustomerPaper.objects.filter(copy_id=forms.customer_id):
                    type = "客戶圖紙"
                else:
                    type = "客戶變更圖紙"
                sendMail(user22222.email,
                         settings.APPROVAL_SUB[3].format(user22222.last_name, type + "(" + sql + ")"),
                         settings.APPROVAL_CONTENT[3].format(user22222.last_name,type + "(" + sql + ")",
                         settings.SYSTEM_ADDRESS + settings.WEB_HRAD[2].format(forms.customer_id, to.token,workflow_id)))
            elif forms.project_id:
                pro_paper = TbProjectPaper.objects.filter(id=forms.project_id)[0]
                sql = pro_paper.custters_spec + pro_paper.stage_type + pro_paper.cutter_type + pro_paper.version
                if TbProjectPaper.objects.filter(id_copy=forms.project_id):
                    type = "工程圖紙"
                else:
                    type = "工程變更圖紙"
                sendMail(user22222.email, settings.APPROVAL_SUB[3].format(user22222.last_name, type + "(" + sql + ")"),
                         settings.APPROVAL_CONTENT[3].format(user22222.last_name, type + "(" + sql + ")",
                         settings.SYSTEM_ADDRESS + settings.WEB_HRAD[3].format(forms.project_id, to.token,workflow_id)))

            else:

                sendMail(user22222.email, settings.APPROVAL_SUB[0].format(user22222.last_name),
                         settings.APPROVAL_CONTENT[0].format(user22222.last_name,
                                                             settings.EMAIL_TEMPLATE["HOST"] + settings.WEB_HRAD[
                                                                 0].format(
                                                                 to.token)))
        else:
            sendMail(user22222.email, settings.APPROVAL_SUB[0].format(user22222.last_name),
                     settings.APPROVAL_CONTENT[0].format(user22222.last_name,
                                                         settings.EMAIL_TEMPLATE["HOST"] + settings.WEB_HRAD[0].format(
                                                             to.token)))


def judging_str(str2):
    """
    用於判斷字符串內是否有數字
    :param str:
    :return:True or False
    """
    numRegular = re.compile(r'.*\d+')
    if numRegular.match(str(str2)):
        return True
    else:
        return False


def every_day_of_month():
    """
    獲取本月每一天的
    :return:
    """
    toDay = dt.date.today()
    if toDay.month < 12:  # 如果當前月份等於 12 則需要將年加一
        monthLastDay = toDay.replace(month=toDay.month + 1, day=1) - dt.timedelta(1)  # 獲取下個月減一天
    else:
        monthLastDay = toDay.replace(year=toDay.year + 1, month=1, day=1) - dt.timedelta(1)  # 獲取明年一月一號 減一天
    thisMonth = toDay.replace(day=1)  # 獲取本月一號
    dayList = []
    for i in range(monthLastDay.day):
        if thisMonth <= monthLastDay:
            dayList.append(thisMonth)
        thisMonth += dt.timedelta(1)
    return dayList


def string_comparison(str1, str2):
    """
    用於字符比較 將字符轉換小寫
    :param str1:
    :param str2:
    :return:
    """
    if str1.lower() == str2.lower():
        return True
    else:
        return False


class WorkflowError(Exception):
    """
    自定義異常
    """

    def __init__(self, data):
        Exception.__init__(self, data)
        self.data = data


def node_case_currency(property, userName, nodeCaseIndex, forms_id, userType=None, org=None):
    """
    用於實例化時userRoles 為空或者為1 是使用
    :param upNum:
    :param upBge:
    :param userName:
    :param nodeCaseIndex:
    :param groupID:
    :return: index
    """
    node_list_2 = {}
    user_list = []
    # nodeCaseIndex = node_case_currency(levelUp,levelBeg,applicant,nodeCaseIndex,groupID.id)
    property['upLevel'] = 0 if not property['upLevel'] else int(property['upLevel'])  # 判斷簽核級數是否有，如果沒有則設定為1，
    for next in range(0, property['upLevel']):
        try:
            if not userType:  # 用於判斷是否是申請者
                if org:
                    orgLevel = Org.objects.filter(id=int(org)).all()[0]
                else:
                    userInfo = User.objects.filter(username=str(userName)).all()[0]  # 獲取申請者信息 org
                    userOrg = UserOrg.objects.filter(user_id=userInfo.id).all()[0]  # 查詢org等級
                    orgLevel = Org.objects.filter(id=userOrg.org_id).all()[0]
                rol = UserOrg.objects.filter(user__username=str(userName), org_role__name="負責人")
                if rol and property['upToLevel'] != '':
                    if orgLevel.org_level_id <= int(property['upToLevel']):  # 用於判斷最高級
                        break
                    userUpInfo = UserOrg.objects.filter(org_id=orgLevel.parent_id, org_role__name="負責人")  # 查詢上一級ID
                elif rol:
                    userUpInfo = UserOrg.objects.filter(org_id=orgLevel.parent_id, org_role__name="負責人")  # 查詢上一級ID
                else:
                    userUpInfo = UserOrg.objects.filter(org_id=orgLevel.id, org_role__name="負責人")  # 查詢上一級ID
                if not userUpInfo:
                    break
                userInfo = User.objects.filter(id=userUpInfo[0].user_id).all()[0]  # 查詢上一級工號
                org = userUpInfo[0].org_id
                username = userInfo.username

            else:
                username = userName
                userType = ''
            username2, name1 = by_agent(username, forms_id)
            user_list.append({"UserID": username2, "UserName": name1 if name1 else userInfo.last_name})

            nodeCaseIndex = nodeCaseIndex + 1
            userName = username  # 保存上一級
            org = userUpInfo[0].org_id


        except Exception as e:
            return '你的職務過高無法申請此該表單，請與管理員瞭解詳情。', '202'
    node_list_2 = {"user_role": user_list, "user_selected": {}, "forward_mode": property['forwordMode'],
                   "forward_back_mode": property['forwardBackMode'], "reject_mode": property['rejectMode'],
                   "forward_list": property['forwardUsers'], "user_mode": property['userMode'],
                   'user_choose': '', 'user_role_list': '', "conditionModel": property['conditionModel']}
    return node_list_2


def by_agent(username, forms_id):
    parentAgent = WorkflowAgent.objects.filter(user_agent__user=username, start_time__lt=datetime.now(),
                                               end_time__gt=datetime.now()).values('user_agent__user',
                                                                                   'user_agent__agent__username',
                                                                                   'user_agent__agent__last_name',
                                                                                   'user_agent__org', 'start_time',
                                                                                   'end_time', 'form_list')
    name = User.objects.filter(username=username)[0].last_name
    if parentAgent:
        for anget in parentAgent:
            if int(forms_id) in eval(anget['form_list'])['id']:
                return anget['user_agent__agent__username'], anget['user_agent__agent__last_name'] + "(代理:{})".format(
                    name)
            else:
                return username, name
    else:
        return username, name


def user_role_currency(roleUser, nodeCaseIndex, property, node_list):
    """
    用於多用戶簽核判斷
    :param roleUser:
    :param nodeCaseIndex:
    :param groupID:
    :param property:
    :return:index
    """
    node_list_2 = {}
    user_list = []
    if string_comparison(property['userMode'], 'MUSTALL') or string_comparison(property['userMode'], 'oneOnly'):  # 平行簽核
        for row, user in enumerate(roleUser, 1):
            # user1 = User.objects.filter(username=user).all()[0]
            user_list.append({"UserID": user[0], "UserName": user[1]})
        node_list_2 = {"user_role": user_list, "user_selected": {}, "forward_mode": property['forwordMode'],
                       "forward_back_mode": property['forwardBackMode'], "reject_mode": property['rejectMode'],
                       "forward_list": property['forwardUsers'], "user_mode": property['userMode'],
                       'user_choose': '', 'user_role_list': '', "conditionModel": property['conditionModel']}
    elif string_comparison(property['userMode'], 'ByApplicant'):
        node_list_2 = {"user_role": [], "user_selected": {}, "forward_mode": property['forwordMode'],
                       "forward_back_mode": property['forwardBackMode'], "reject_mode": property['rejectMode'],
                       "forward_list": property['forwardUsers'], "user_mode": property['userMode'],
                       'user_choose': roleUser, 'user_role_list': '', "conditionModel": property['conditionModel']}
    elif string_comparison(property['userMode'], 'ByLastNode'):  # 用戶需要選擇
        if nodeCaseIndex <= 1:
            if 'user_role_list' in node_list['case'][-1]:
                node_list['case'][-1]['user_role_list'] = roleUser
        node_list_2 = {"user_role": [], "user_selected": {}, "forward_mode": property['forwordMode'],
                       "forward_back_mode": property['forwardBackMode'], "reject_mode": property['rejectMode'],
                       "forward_list": property['forwardUsers'], "user_mode": property['userMode'],
                       'user_choose': roleUser, 'user_role_list': '', "conditionModel": property['conditionModel']}
        nodeCaseIndex += 1
    elif string_comparison(property['userMode'], 'conditionModel'):  # 用戶需要選擇
        for row, user in enumerate(roleUser, 1):
            # user1 = User.objects.filter(username=user).all()[0]
            user_list.append({"UserID": user[0], "UserName": user[1]})
        node_list_2 = {"user_role": user_list, "user_selected": {}, "forward_mode": "noForward",
                       "forward_back_mode": "", "reject_mode": "AllowToSelect",
                       "forward_list": "", "user_mode": property['userMode'],
                       'user_choose': '', 'user_role_list': '', "conditionModel": property['conditionModel']}
    return node_list_2


def user_mail(sub, username, value):
    """
    用於發郵件通知簽核人簽核郵件
    :return:
    """
    try:
        data = settings.EMAiL_FROM
        user = User.objects.filter(username=username)[0]
        data['toMail'] = user.email
        data["mail_title"] = "你有一筆" + value + "," + sub
        data["content"] = settings.EMAIL_DATA
        url = 'http://10.129.4.95:9090/data_manage/'
        # return requests.post(url, data=json.dumps(data))
    except Exception as e:
        return username + "不存在請註冊"


def one_approval(nextID, index, wkID, username):
    """
    用於簽核后查詢下一個節點的簽核人及郵件發送
    :param node_id:
    :return:
    """
    groupID, number = nextID.split('-')
    nodeCase = NodeCase.objects.filter(group_id=groupID).all()  # 查詢組內全部的節點實例
    coun = list(set([i.order_number for i in nodeCase]))
    if len(coun) > int(number):  # 判斷當前節點是否是最高一個節點
        nodeCase = NodeCase.objects.filter(order_number=int(number) + 1, group_id=groupID).all()  # 查詢下一個節點
        # NodeCase.objects.filter(id=nodeCase[0].id).update(status='待簽核')
        mailtototot(nodeCase[0].approver, wkID)
        WorkflowApprovalRecord.objects.create(workflow_record_id=wkID, status=0, approver=nodeCase[0].approver,
                                              next=str(nodeCase[0].group_id) + '-' + str(nodeCase[0].order_number),
                                              start_time=datetime.now(), order_number=index + 1)


        # user_mail('待你簽核，請及時查看',approver,workflow.name)
    else:  # 當節點為最後等於節點和的話就需要找到下一個組
        nodeGroupID = NodeGroup.objects.filter(id=groupID).all()[0]  # 查詢當前節點的組
        if len(NodeGroup.objects.filter(
                workflowrecord_id=nodeGroupID.workflowrecord_id)) > nodeGroupID.order_number:  # 判斷當前的組是否是最後一個組
            nodeGroupID = NodeGroup.objects.filter(workflowrecord_id=nodeGroupID.workflowrecord_id,
                                                   order_number=int(nodeGroupID.order_number) + 1)[0]  # 查詢下一個組
            nodeCase = NodeCase.objects.filter(group_id=nodeGroupID.id, order_number=1)  # 下一個組對應的第一個節點

            if len(nodeCase) > 1:  # 判斷第一個節點是否是有多人簽核
                nextApprover = next_approver(nodeCase[0].group_id, nodeCase[0].order_number)
                for node in nodeCase:
                    mailtototot(node.approver, wkID)
                    WorkflowApprovalRecord.objects.create(workflow_record_id=wkID, status=0,
                                                          approver=node.approver,
                                                          next=str(node.group_id) + '-' + str(node.order_number),
                                                          start_time=datetime.now(), order_number=index + 1,
                                                          next_approver=nextApprover)

            elif len(nodeCase) == 1:
                nextApprover, by = next_approver(nodeCase[0].group_id, nodeCase[0].order_number)
                if by == 'byuser':
                    appli = Workflowrecord.objects.filter(id=wkID).values('applicant')
                    mailtototot(appli[0]['applicant'], wkID)
                    WorkflowApprovalRecord.objects.create(workflow_record_id=wkID, status=0,
                                                          approver=appli[0]['applicant'],
                                                          next=str(nodeCase[0].group_id) + '-' + str(
                                                              nodeCase[0].order_number),
                                                          start_time=datetime.now(), order_number=index + 1,
                                                          next_approver=nextApprover)
                else:
                    if username:
                        mailtototot(username, wkID)
                        WorkflowApprovalRecord.objects.create(workflow_record_id=wkID, status=0, approver=username,
                                                              next=str(nodeCase[0].group_id) + '-' + str(
                                                                  1),
                                                              start_time=datetime.now(), order_number=index + 1,
                                                              next_approver=nextApprover)
                    else:
                        mailtototot(nodeCase[0].approver, wkID)
                        WorkflowApprovalRecord.objects.create(workflow_record_id=wkID, status=0,
                                                              approver=nodeCase[0].approver,
                                                              next=str(nodeCase[0].group_id) + '-' + str(
                                                                  nodeCase[0].order_number),
                                                              start_time=datetime.now(), order_number=index + 1,
                                                              next_approver=nextApprover)

                        # user_mail('待你簽核，請及時查看',approver,workflow.name)
        else:  # 當節點為最後一個且組也為最後一個時簽核完成
            data = Workflowrecord.objects.filter(id=nodeGroupID.workflowrecord_id)
            data.update(end_time=datetime.now(), status=1)


def forward_(nextID, nodePropety, nodeData, node_id, index):
    """
    用於轉呈
    :param nextID:
    :param nodePropety:
    :param nodeData:
    :param node_id:
    :param index:
    :return:
    """
    groupID, number = nextID.split('-')
    forms_id = TbApplyform.objects.filter(wrecord=nodeData[0].workflow_record_id)[0].form_id
    if string_comparison(nodePropety.forward_back_mode, 'BackToMe'):
        nodeCaseCount = NodeCase.objects.filter(group_id=groupID, order_number=number)
        nodeGroupOne = NodeGroup.objects.filter(workflowrecord_id=nodeData[0].workflow_record_id).all()[0]

        if string_comparison(nodePropety.forward_mode, 'ByUsers'):
            for user in eval(nodeCaseCount[0].forward_list):
                user, name = by_agent(user, forms_id)
                mailtototot(user, nodeData[0].workflow_record_id)
                WorkflowApprovalRecord.objects.create(workflow_record_id=nodeData[0].workflow_record_id, status=0,
                                                      approver=user,
                                                      next=str(groupID) + '-' + str(int(number) - 1),
                                                      start_time=datetime.now(), order_number=index + 1)
        else:
            node_id['username'], name = by_agent(node_id['username'], forms_id)
            mailtototot(node_id['username'], nodeData[0].workflow_record_id)
            WorkflowApprovalRecord.objects.create(workflow_record_id=nodeData[0].workflow_record_id, status=0,
                                                  approver=node_id['username'],
                                                  next=str(groupID) + '-' + str(
                                                      int(number) - 1 if int(number) else int(number)),
                                                  start_time=datetime.now(), order_number=index + 1)

    elif string_comparison(nodePropety.forward_back_mode, 'BackToNext'):
        nodeGroupOne = NodeGroup.objects.filter(workflowrecord_id=nodeData[0].workflow_record_id).all()[0]
        nodeCaseCount = NodeCase.objects.filter(group_id=groupID)

        if nodeGroupOne.order_number <= int(groupID) and nodeCaseCount.count() <= int(number):
            if string_comparison(nodePropety.forward_mode, 'ByUsers'):

                for user in eval(nodeCaseCount[0].forward_list):
                    user, name = by_agent(user, forms_id)
                    mailtototot(user, nodeData[0].workflow_record_id)
                    WorkflowApprovalRecord.objects.create(workflow_record_id=nodeData[0].workflow_record_id, status=0,
                                                          approver=user,
                                                          next=str(groupID) + '-' + str(number),
                                                          start_time=datetime.now(), order_number=index + 1)
                    # user_mail('待你簽核，請及時查看',user,workflow.name)
            else:
                node_id['username'], name = by_agent(node_id['username'], forms_id)
                mailtototot(node_id['username'], nodeData[0].workflow_record_id)
                WorkflowApprovalRecord.objects.create(workflow_record_id=nodeData[0].workflow_record_id, status=0,
                                                      approver=node_id['username'],
                                                      next=str(groupID) + '-' + str(number),
                                                      start_time=datetime.now(), order_number=index + 1)
                # user_mail('待你簽核，請及時查看',node_id['username'],workflow.name)
        else:
            if string_comparison(nodePropety.forward_mode, 'ByUsers'):
                for user in eval(nodeCaseCount[0].forward_list):
                    user, name = by_agent(user, forms_id)
                    mailtototot(user, nodeData[0].workflow_record_id)
                    WorkflowApprovalRecord.objects.create(workflow_record_id=nodeData[0].workflow_record_id, status=0,
                                                          approver=user,
                                                          next=str(groupID) + '-' + str(number),
                                                          start_time=datetime.now(), order_number=index + 1)
                    # user_mail('待你簽核，請及時查看',user,workflow.name)
            else:
                node_id['username'], name = by_agent(node_id['username'], forms_id)
                mailtototot(node_id['username'], nodeData[0].workflow_record_id)
                WorkflowApprovalRecord.objects.create(workflow_record_id=nodeData[0].workflow_record_id, status=0,
                                                      approver=node_id['username'],
                                                      next=str(groupID) + '-' + str(int(number)),
                                                      start_time=datetime.now(), order_number=index + 1)
                # user_mail('待你簽核，請及時查看',node_id['username'],workflow.name)


def next_approver(groupID, number):
    """
    用於解析下一個實例化節點的用戶
    :param groupID:
    :param number:
    :return:
    """

    nodeCase = NodeCase.objects.filter(group_id=groupID).all()  # 查詢組內全部的節點實例
    coun = list(set([i.order_number for i in nodeCase]))
    nextApprover = []
    if len(coun) > number:
        nextNodeCase = NodeCase.objects.filter(group_id=groupID, order_number=number + 1)
        if nextNodeCase[0].user_mode == 'ByLastNode':  # 判斷下一條記錄是否是需要選擇
            for i in nextNodeCase[0].user_role_list:  # 解析下一條記錄列表中的角色以及工號
                if judging_str(i):
                    nextApprover.append(i)
                else:
                    role = WorkflowRole.objects.filter(role=i).all()[0]  # 查詢角色表
                    # roleUser = WorkflowRoleUser.objects.filter(workflow_role_id=role.id).all() #查詢角色對應的工號
                    orgRole = WFSOrgRole.objects.filter(role_id=role.id)
                    for org in orgRole:
                        for row in UserOrg.objects.filter(org_id=org.org_id):
                            userName = User.objects.filter(id=row.id)[0]
                            nextApprover.append(userName.username)

    else:
        nodeGroupID = NodeGroup.objects.filter(id=groupID).all()[0]  # 查詢當前節點的組
        group = NodeGroup.objects.filter(workflowrecord_id=nodeGroupID.workflowrecord_id)
        if len(group) > nodeGroupID.order_number:  # 判斷當前的組是否是最後一個組
            index = int(nodeGroupID.order_number)
            # nodeGroupID = NodeGroup.objects.filter(workflowrecord_id=nodeGroupID.workflowrecord_id,
            #                                        order_number=index+1)[0] #查詢下一個主
            nextNodeCase = NodeCase.objects.filter(group_id=nodeGroupID.id, order_number=1)  # 下一個組對應的第一個節
            if not nextNodeCase:
                nodeGroupID = NodeGroup.objects.filter(workflowrecord_id=nodeGroupID.workflowrecord_id,
                                                       order_number=index + 1)[0]  # 查詢下一個主
                nextNodeCase = NodeCase.objects.filter(group_id=nodeGroupID.id, order_number=1)
            if nextNodeCase[0].user_role_list:
                nextApprover = nextNodeCase[0].user_role_list
                return nextApprover, "bynode"
            elif nextNodeCase[0].user_choose:
                nextApprover = nextNodeCase[0].user_choose
                return nextApprover, 'byuser'
    return nextApprover, ''


from django.db import transaction


def case(user, desc, org, workflowID, userList, forms_id):
    try:
        workflow_list = {}
        with transaction.atomic():
            if not userList:
                try:
                    org = org if org else UserOrg.objects.filter(user_id=user.id)  # 判斷用戶有沒有選擇Org
                    if not org:
                        return "請確認你是否在組織內", '202'
                    else:
                        if not isinstance(org, int):
                            org = org[0].org_id
                except:
                    return "請確認你是否在組織內", '202'
                workflow_list = {"workflow_id": workflowID,
                                 "type": Workflow.objects.filter(id=workflowID)[0].workflow_type,
                                 "applicant": user.username, "desc": desc, "username": user.last_name, "case": []}
                node = Workflownode.objects.all().filter(workflow_id=workflowID).order_by('order_number')
                nodeGroupIndex = 1
                for i in node:
                    nodeCaseIndex = 1
                    workflow_list["case"].append({"name": i.name, "order_number": nodeGroupIndex, "node": []})
                    property = eval(i.property)
                    lowerProperty = eval(i.property.lower())
                    if not property['userRoles']:  # userroles為空時，直接查詢登陸者組織
                        # 寫入記錄表
                        if 'lowerToLevel' in property and property['lowerToLevel'] != '':
                            if property['lowerToLevel']:
                                s = node_case_by_level(property, user.username, nodeCaseIndex, forms_id, org=org)
                            else:
                                s = node_case_currency(property, user.username, nodeCaseIndex, forms_id, org=org)
                        else:
                            s = node_case_currency(property, user.username, nodeCaseIndex, forms_id, org=org)
                        if isinstance(s, tuple):
                            return s
                        else:
                            workflow_list['case'][nodeGroupIndex - 1]['node'] = s

                    elif len(property['userRoles']) == 1:  # userroles長度為1，查詢該用戶的組織
                        role_id = []
                        if judging_str(property['userRoles'][0]):  # True 就為工號 False 為 角色名
                            userName = property['userRoles'][0]  # 提取工號
                            nar = TbWorkflowRole2.objects.filter(id=userName)[0].username
                            nar, name = by_agent(nar, forms_id)
                        else:
                            role = property['userRoles'][0]
                            for users in WFSOrgRole.objects.filter(role__role=role).values("user__username"):
                                role_id.append(users["user__username"])
                            if len(role_id) > 1:
                                nar = ''
                            elif len(role_id) == 1:
                                nar = role_id[0]
                            else:
                                continue
                        if nar:
                            if (property['upToLevel'] or property['lowerToLevel']) and property['upLevel']:  # 按組織執行
                                if property['lowerToLevel'] != '':
                                    s = node_case_by_level(property, nar, nodeCaseIndex, forms_id)
                                else:
                                    s = node_case_currency(property, user.username, nodeCaseIndex, forms_id, org=org)
                                if isinstance(s, tuple):
                                    return s
                                else:
                                    workflow_list['case'][nodeGroupIndex - 1]['node'] = s
                            else:  # 按個人執行
                                username, name = by_agent(nar, forms_id)
                                workflow_list['case'][nodeGroupIndex - 1]['node'] = {
                                    "user_role": [{'UserID': username, "UserName": name}],
                                    "user_selected": {}, "forward_mode": property['forwordMode'],
                                    "forward_back_mode": property['forwardBackMode'],
                                    "reject_mode": property['rejectMode'],
                                    "forward_list": property['forwardUsers'], "user_mode": property['userMode'],
                                    "username": name, 'user_choose': '', 'user_role_list': '',
                                    "conditionModel": property['conditionModel']}
                        else:
                            role = [by_agent(i, forms_id) for i in role_id]
                            node_list = user_role_currency(role, nodeCaseIndex, property, workflow_list)
                            workflow_list['case'][nodeGroupIndex - 1]['node'] = node_list
                    elif len(property['userRoles']) > 1:  # userroles長度大於1，直接記錄userRoles中的用戶
                        roleUser = []
                        nar = []
                        for i in property['userRoles']:
                            if judging_str(i):  # True 就為工號 False 為 角色名
                                userName = by_agent(i, forms_id)[0]  # 提取工號
                                roleUser.append(TbWorkflowRole2.objects.filter(id=userName)[0].username)
                            else:
                                role = i
                                for users in WFSOrgRole.objects.filter(role__role=role).values("user__username"):
                                    username, name = by_agent(users["user__username"], forms_id)
                                    roleUser.append([username, name])

                        # for users in property['userRoles']:
                        #     nar = TbWorkflowRole2.objects.filter(id=users)
                        #     username,name = by_agent(nar[0].username,forms_id)
                        #     roleUser.append(username)
                        node_list = user_role_currency(roleUser, nodeCaseIndex, property, workflow_list)
                        workflow_list['case'][nodeGroupIndex - 1]['node'] = node_list
                    nodeGroupIndex += 1
    except WorkflowError as e:
        return str(e)
    return workflow_list


    #

    # nodeGroup = NodeGroup.objects.filter(workflowrecord_id=caseWorkflow.id).order_by('order_number')[0]
    # nodeCase = NodeCase.objects.filter(group_id=nodeGroup.id,order_number=1).order_by('order_number')
    # nextApprover = next_approver(nodeGroup.id,1)
    #
    # toUser = ''
    # img = User.objects.filter(username=caseWorkflow.applicant)
    # WorkflowApprovalRecord.objects.create(start_time=datetime.now(),end_time=datetime.now(),approver=caseWorkflow.applicant,
    #                                           next=0,status=1,
    #                                           order_number=1,workflow_record_id=caseWorkflow.id,next_approver=nextApprover,action='發起',signature=img[0].sign)
    #
    # if nodeCase:
    #     for node in nodeCase:
    #         WorkflowApprovalRecord.objects.create(start_time=datetime.now(),approver=node.approver,
    #                                           next=str(node.group_id)+'-'+str(node.order_number),status=0,
    #                                           order_number=2,workflow_record_id=caseWorkflow.id,next_approver=nextApprover,username=node.username)
    # else:
    #     if not nodeCase:
    #             nodeGroupID = NodeGroup.objects.filter(workflowrecord_id=caseWorkflow.id,
    #                                                order_number=nodeGroup.order_number+1) #查詢下一個主
    #             if nodeGroupID:
    #                 node = NodeCase.objects.filter(group_id=nodeGroupID[0].id,order_number=1)[0]
    #             else:
    #                  return '你的職務過高無法申請此該表單，請與管理員瞭解詳情。','202'
    #     WorkflowApprovalRecord.objects.create(start_time=datetime.now(),approver=node.approver,
    #                                               next=str(node.group_id)+'-'+str(node.order_number),status=0,
    #                                               order_number=2,workflow_record_id=caseWorkflow.id,next_approver=nextApprover,username=node.username)
    # toUser +=node.username+'(%s)'%node.approver if not toUser else ','+node.username+'(%s)'%node.approver
    #
    # cuidan = {'type':'faqi',"from":user.last_name+'(%s)'%user.username,
    #            'to':toUser,'date':datetime.now().strftime('%Y-%m-%d %H:%M:%S'),'message':{'no':card_id,'type':"發起動態",'time':datetime.now().strftime('%Y-%m-%d %H:%M:%S'),'title':"【表單簽核】您有一筆表單需要簽核",'url':"/form:"+forms_id},'content':[{'from_id':'', 'from_mo':'','from_name':'','initial_date':datetime.now().strftime('%Y-%m-%d %H:%M:%S'),'current_approver':user.first_name+'(%s)'%user.username,
    #                                                          'current_approve_date':datetime.now().strftime('%Y-%m-%d %H:%M:%S'),'current_approve_status':'pass',
    #                                                          'current_approve_comment':desc,'next_approver':toUser,'status':'pass'}]}
    #
    #
    #
    # return caseWorkflow.id,cuidan


import threading


def xiaoxituisong(action, user, wroid):
    from files import models
    apply = models.TbApplyform.objects.filter(wrecord_id=wroid)[0]
    customer_id = apply.customer_id
    project_id = apply.project_id
    if customer_id:
        url = "../templates/module1/index.html#/drawcuscheck/:{}?action=check&wr={}".format(customer_id,wroid)
        title = "【客戶圖紙簽核】您有一筆表單需要簽核"
    elif project_id:
        url = "../templates/module1/index.html#/drawengcheck/:{}?action=check&wr={}".format(project_id,wroid)
        title = "【工程圖紙簽核】您有一筆表單需要簽核"
    else:
        url = "../templates/module1/index.html#/form:" + str(apply.id)
        title = "【表單簽核】您有一筆表單需要簽核"
    approval = WorkflowApprovalRecord.objects.filter(workflow_record_id=apply.wrecord_id,
                                                     approver=user.username).exclude(status=0).order_by('-end_time')
    if approval:
        actiondict = {'通過': 'pass', '駁回': 'rejected', '轉呈': 'forward', '棄權': 'giveup'}
        action = actiondict[approval[0].action]
        current = approval[0].end_time
        username = approval[0].username if approval[0].username else ''
        approval = username + '(' + approval[0].approver + ')'
    else:
        approval = apply.applicant + '(' + User.objects.filter(username=apply)[0].last_name + ')'
        current = apply.apply_time
        action = "pass"
    for node in WorkflowApprovalRecord.objects.filter(workflow_record_id=apply.wrecord_id, status=0):
        username = node.username if node.username else ''
        cuidan = {'type': 'qianhe',
                  'from': apply.applicant + '(' + User.objects.filter(username=apply.applicant)[0].last_name + ')',
                  'to': username + '(%s)' % node.approver, 'date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                  'message': {'no': apply.card_id, 'type': "簽單動態", 'time': "2017-06-27 11:55:08",
                              'title': title,
                              'url': url},
                  'content': [{'form_id': apply.id, 'form_no': apply.card_id,
                               'form_name': apply.name, 'initial_date': apply.apply_time.strftime('%Y-%m-%d %H:%M:%S'),
                               'current_approver': approval,
                               'current_approve_date': current.strftime('%Y-%m-%d %H:%M:%S'),
                               'current_approve_status': action, 'current_approve_comment': str(apply.desc),
                               'next_approver': username + '(%s)' % node.approver, 'status': 'open'}]}
        log = ReminderLog.objects.create(no=apply.card_id, rectime=datetime.now(), applicant=apply.applicant,
                                         user=username + '(%s)' % node.approver,
                                         name=User.objects.filter(username=apply.applicant)[0].last_name,
                                         title=cuidan['message']['title'],
                                         type=cuidan['message']['type'], url=cuidan['message']['url'], status=0)
        cuidan['message']['id'] = log.id
        message = threading.Thread(target=cccc, args=(str(cuidan),))
        message.setDaemon(True)
        message.start()


def by_username(node):
    userList = []
    if type(node) == str:
        node = eval(node)
    if node['userRoles']:
        for i in node['userRoles']:
            if judging_str(i):
                wor = TbWorkflowRole2.objects.filter(username=i)
                if not wor:
                    roleID = TbWorkflowRole2.objects.create(username=i)
                    userList.append(roleID.id)
                else:
                    userList.append(wor[0].id)
            else:
                userList.append(i)

    node['userRoles'] = userList
    return node


def cccc(data):
    try:
        # requests.get('http://'+settings.MQTT+'/?topic=st/message&qos=2&message='+data)
        return 1
    except:
        return 0


def oneNode(caseID, nodeNumber, groupNumber=None):
    groupNumber = groupNumber - 1 if groupNumber else 0
    nodeGroup = NodeGroup.objects.filter(workflowrecord_id=caseID).order_by('order_number')[0]
    nodeCase = NodeCase.objects.filter(group_id=nodeGroup.id, order_number=1).order_by('order_number')
    nextApprover = next_approver(nodeGroup.id, 1)
    if nodeCase:
        for node in nodeCase:
            return str(node.group_id) + '-' + str(node.order_number - 1)
    else:
        if not nodeCase:
            nodeGroupID = NodeGroup.objects.filter(workflowrecord_id=caseID,
                                                   order_number=nodeGroup.order_number + 1)[0]  # 查詢下一個主
            node = NodeCase.objects.filter(group_id=nodeGroupID.id, order_number=1)[0]

        return str(node.group_id) + '-' + str(node.order_number - 1)


def node_case_by_level(property, username, index, forms_id, org=None):
    """
    指定等級簽核
    :param property:
    :param username:
    :param index:
    :param group:
    :return:
    """

    userInfo = User.objects.filter(username=str(username)).all()[0]  # 獲取申請者信息 org
    if org:
        org2 = \
            UserOrg.objects.filter(org_id=org, user_id=userInfo.id).values('org_id', 'org__org_level',
                                                                           'org_role__name')[0]
    else:
        org2 = UserOrg.objects.filter(user_id=userInfo.id).values('org_id', 'org__org_level', 'org_role__name')[0]
    if int(property['lowerToLevel']) + 5 > int(org2['org__org_level']) and org2['org_role__name'] != 2:
        username = userInfo.username
    else:
        org3 = UserOrg.objects.filter(org_id=org2['org_id'], org_role__name='負責人').values('user__username', 'org_id',
                                                                                          'org__org_level')[0]
        username, level, userOrg = org3['user__username'], org3['org__org_level'], org3['org_id']
        while int(property['lowerToLevel']) + 5 < int(level):
            try:
                org3 = \
                    UserOrg.objects.filter(org_id=userOrg, org_role__name='負責人').values('org__parent_id',
                                                                                        'org__org_level',
                                                                                        'org_id', 'user__username',
                                                                                        'user__last_name')[0]
                username, level, userOrg, org = org3['user__username'], org3['org__org_level'], org3['org__parent_id'], \
                                                org3['org_id']
            except:
                return '最低簽核無法找到,確認你是否適用該表單(你組織內未找到級別到達最低簽核級別)', '202'
    return node_case_currency(property, username, index, forms_id, org=org)


def work_build(data, pdf, desc, card_id, user, forms_id, customer_id=None, project_id=None):
    if not data["case"]:
        return "無簽核人員", '202'
    try:
        with transaction.atomic():
            caseWorkflow = Workflowrecord.objects.create(workflow_id=data["workflow_id"], applicant=data["applicant"],
                                                         status=0,
                                                         create_time=datetime.now(), desc=desc,
                                                         username=data["username"])
            group_id_list = []
            index = 1
            toUser = ''
            for i in data["case"]:
                if i["node"]:
                    row = i["node"]
                    if string_comparison(row["user_mode"], "conditionModel"):
                        if not row["user_selected"]:
                            continue
                    groupID = NodeGroup.objects.create(name=i['name'], workflowrecord_id=caseWorkflow.id,
                                                       order_number=index)
                    if string_comparison(row["user_mode"], "oneOnly") or string_comparison(row["user_mode"],
                                                                                           "conditionModel"):
                        if not row["user_selected"]:
                            return "請選擇簽核人", 202
                        NodeCase.objects.create(order_number=1, group_id=groupID.id, rectime=datetime.now(),
                                                approver=row["user_selected"]["UserID"],
                                                forward_mode=row["forward_mode"],
                                                forward_back_mode=row["forward_back_mode"],
                                                reject_mode=row["reject_mode"], status=0,
                                                forward_list=row["forward_list"],
                                                user_mode=row["user_mode"],
                                                username="")  # row["user_selected"]["UserName"]
                    else:
                        index2 = 1
                        for i in row["user_role"]:
                            if data["type"] == "self":
                                username, name = by_agent(i["UserID"], forms_id)
                                NodeCase.objects.create(order_number=index2, group_id=groupID.id,
                                                        rectime=datetime.now(),
                                                        approver=username, forward_mode="noForward",
                                                        forward_back_mode="",
                                                        reject_mode="AllowToSelect", status=0, forward_list="",
                                                        user_mode="oneOnly",
                                                        username=name + "(代理" + i["UserName"] + ")")
                            else:
                                NodeCase.objects.create(order_number=index2, group_id=groupID.id,
                                                        rectime=datetime.now(),
                                                        approver=i["UserID"], forward_mode=row["forward_mode"],
                                                        forward_back_mode=row["forward_back_mode"],
                                                        reject_mode=row["reject_mode"], status=0,
                                                        forward_list=row["forward_list"],
                                                        user_mode=row["user_mode"], username=i["UserName"])
                            if not string_comparison(row["user_mode"], "MUSTALL"):
                                index2 += 1
                    group_id_list.append(groupID.id)
                    index += 1
            img = User.objects.filter(username=caseWorkflow.applicant)
            WorkflowApprovalRecord.objects.create(start_time=datetime.now(), end_time=datetime.now(),
                                                  approver=caseWorkflow.applicant,
                                                  next=0, status=1,
                                                  order_number=1, workflow_record_id=caseWorkflow.id,
                                                  next_approver="()", action='發起', signature=img[0].sign)
            nextApprover = next_approver(group_id_list[0], 1)
            for node in NodeCase.objects.filter(group=group_id_list[0], order_number=1):

                mailtototot(node.approver, caseWorkflow.id, customer_id, project_id)

                WorkflowApprovalRecord.objects.create(start_time=datetime.now(), approver=node.approver,
                                                      next=str(node.group_id) + '-' + str(node.order_number), status=0,
                                                      order_number=2, workflow_record_id=caseWorkflow.id,
                                                      next_approver=nextApprover, username=node.username)
                toUser += node.username + '(%s)' % node.approver if not toUser else ',' + node.username + '(%s)' % node.approver
            if customer_id:
                url ="../templates/module1/index.html#/drawcuscheck/:{}?action=check&wr={}".format(customer_id,caseWorkflow.id)
                title= "【客戶圖紙簽核】您有一筆表單需要簽核"
            elif project_id:
                url = "../templates/module1/index.html#/drawengcheck/:{}?action=check&wr={}".format(project_id,caseWorkflow.id)
                title = "【工程圖紙簽核】您有一筆表單需要簽核"
            else:
                url = "../templates/module1/index.html#/form:" + forms_id
                title = "【表單簽核】您有一筆表單需要簽核"
                cuidan = {'type': 'faqi', "from": user.last_name + '(%s)' % user.username,
                          'to': toUser, 'date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                          'message': {'no': card_id, 'type': "發起動態",
                                      'time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                                      'title': title,
                                      'url': url}, 'content': [
                        {'from_id': '', 'from_mo': '', 'from_name': '',
                         'initial_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                         'current_approver': user.first_name + '(%s)' % user.username,
                         'current_approve_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                         'current_approve_status': 'pass',
                         'current_approve_comment': desc, 'next_approver': toUser, 'status': 'pass'}]}
                return caseWorkflow.id, cuidan

            cuidan = {'type': 'faqi', "from": user.last_name + '(%s)' % user.username,
                      'to': toUser, 'date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                      'message': {'no': card_id, 'type': "發起動態", 'time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                                  'title': title,
                                  'url': url}, 'content': [
                    {'from_id': '', 'from_mo': '', 'from_name': '',
                     'initial_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                     'current_approver': user.first_name + '(%s)' % user.username,
                     'current_approve_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                     'current_approve_status': 'pass',
                     'current_approve_comment': desc, 'next_approver': toUser, 'status': 'pass'}]}

            log = ReminderLog.objects.create(no=card_id, rectime=datetime.now(), applicant=data["applicant"],
                                             user=toUser,
                                             name=User.objects.filter(username=data["applicant"])[0].last_name,
                                             title=cuidan['message']['title'],
                                             type=cuidan['message']['type'], url=cuidan['message']['url'], status=0)
            cuidan['message']['id'] = log.id
            message = threading.Thread(target=cccc, args=(str(cuidan),))
            message.setDaemon(True)
            message.start()
            return caseWorkflow.id, cuidan
    except WorkflowError as e:
        return e, '202'
